function [gbest,gbestval,fitcount] = ABC_func(fhd,Dimension,Particle_Number,Max_Gen,lowerbound,upperbound,pos,bool_Plot,varargin)

rand('state',sum(100*clock));
me = Max_Gen;
ps = Particle_Number;
D = Dimension;
NumFood = fix(ps/2)+1;
limit = ps*D/5;
% limit = 150;

[pub, plb, vub, vlb] = SetBound(D,ps,lowerbound,upperbound);
% pos = VRmin+(VRmax-VRmin).*rand(ps,D);

% vel = zeros(ps,D); % initialize the velocity of the particles
% acc = zeros(ps,D); % initialize the acceleration of the particles
Food = pos(1:NumFood,:);
Trial = zeros(NumFood,1);

fitcount = ps;
fitness = feval(fhd,Food',varargin{:});
% sort_fitness = [fitness' (1:ps)'];
% sort_fitness = sortrows(sort_fitness, 1);
[fitbest,gbestindex] = min(fitness);
fitworst = max(fitness);
% gbestindex = sort_fitness(1,2);
gbest = Food(gbestindex,:);
gbestval = fitbest;

if(bool_Plot)
    figure(7)
    haxes = plot( 0 , 0 );
    XArray = [1];
    YArray = [gbestval];
    title('ABC');
end

for iter = 2:me
    % Employed bee phase
    for n = 1 : NumFood
        index_d = fix(rand()*D) + 1; % Select dth parameter for change
        index_n = fix(rand()*NumFood) + 1; % Select nth food source as the neighbour 
        
        while(index_n == n)
            index_n = fix(rand()*NumFood) + 1;
        end
        
        candidate_newfood = Food(n,:);
        candidate_newfood(1,index_d) = Food(n,index_d) + (Food(n,index_d)-Food(index_n,index_d)) * (2*rand-1);
        candidate_newfood = ((candidate_newfood>=plb(n,:))&(candidate_newfood<=pub(n,:))).*candidate_newfood+...
                            (candidate_newfood<plb(n,:)).*plb(n,:)+(candidate_newfood>pub(n,:)).*pub(n,:);
                        
        fitcount = fitcount + 1;
        fitness_candidate = feval(fhd,candidate_newfood',varargin{:});
        if(fitness_candidate < fitness(n)) % For minimization problem
            Food(n,:) = candidate_newfood;
            fitness(n) = fitness_candidate;
            Trial(n) = 0;
        else
            Trial(n) = Trial(n) + 1;
        end
    end
        
    
    % Onlooker bee phase
    for n = 1 : NumFood
%         index_f = fix(rand()*NumFood) + 1;
        fitbest = min(fitness);
        fitworst = max(fitness);
        if(fitbest == fitworst)
            mass = repmat(1/NumFood,NumFood,1);
        else
            mass = (fitness'-fitworst)/(fitbest-fitworst);
        end
        mass = mass / sum(mass);
        index_f = RouletteWheel(mass,1);
        
        index_d = fix(rand()*D) + 1; % Select dth parameter for change
        index_n = fix(rand()*NumFood) + 1; % Select nth food source as the neighbour 
        
        while(index_n == index_f)
            index_n = fix(rand()*NumFood) + 1;
        end
        
        candidate_newfood = Food(index_f,:);
        candidate_newfood(1,index_d) = Food(index_f,index_d) + (Food(index_f,index_d)-Food(index_n,index_d)) * (2*rand-1);
        candidate_newfood = ((candidate_newfood>=plb(n,:))&(candidate_newfood<=pub(n,:))).*candidate_newfood+...
                            (candidate_newfood<plb(n,:)).*plb(n,:)+(candidate_newfood>pub(n,:)).*pub(n,:);
                        
        fitcount = fitcount + 1;
        fitness_candidate = feval(fhd,candidate_newfood',varargin{:});
        if(fitness_candidate < fitness(n)) % For minimization problem
            Food(n,:) = candidate_newfood;
            fitness(n) = fitness_candidate;
            Trial(n) = 0;
        else
            Trial(n) = Trial(n) + 1;
        end
    end
    
    % Scout bee phase
    [max_trial, index_trial] = max(Trial);
    if(max_trial > limit)
        Trial(index_trial) = 0;
        Food(index_trial, :) = plb(index_trial, :)+(pub(index_trial, :)-plb(index_trial, :)).*rand(1,D);
        fitness(index_trial) = feval(fhd,Food(index_trial, :)',varargin{:});
    end
    
%     fitness = feval(fhd,pos',varargin{:});
%     sort_fitness = [fitness' (1:ps)'];
%     sort_fitness = sortrows(sort_fitness, 1);
    [fitbest,gbestindex] = min(fitness);
    fitworst = max(fitness);
%     gbestindex = sort_fitness(1,2);
    gbest = Food(gbestindex,:);
    gbestval = fitbest;
    
    if(bool_Plot)
        XArray = [ XArray iter]; 
        YArray = [ YArray gbestval];
        set( haxes , 'XData' , XArray , 'YData' , YArray );
        drawnow
    end
end

end